﻿using Microsoft.Extensions.Logging;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BCVP.Net8.Repository.UnitOfWorks
{
    // 定义一个名为 UnitOfWork 的公共类，并实现 IDisposable 接口
    // IDisposable 接口用于释放非托管资源（在这里主要是数据库连接和事务）
    public class UnitOfWork : IDisposable
    {
        // 1. 属性定义
        // ILogger: 用于记录日志的接口，方便调试和追踪 UnitOfWork 的状态变化
        public ILogger Logger { get; set; }
        // ISqlSugarClient: SqlSugar ORM 的数据库客户端接口，用于执行数据库操作
        public ISqlSugarClient Db { get; internal set; }
        // ITenant: SqlSugar 的多租户接口，用于管理数据库事务
        public ITenant Tenant { get; internal set; }
        // IsTran: 布尔值，指示当前是否处于一个数据库事务中
        public bool IsTran { get; internal set; }
        // IsCommit: 布尔值，指示事务是否已经被提交
        public bool IsCommit { get; internal set; }
        // IsClose: 布尔值，指示数据库连接是否已经被关闭
        public bool IsClose { get; internal set; }

        // 2. Dispose 方法 (实现 IDisposable 接口)
        // 当 UnitOfWork 对象被释放时（例如，使用 using 语句块结束时），会自动调用此方法
        public void Dispose()
        {
            // a. 检查是否需要回滚事务
            // 如果当前处于事务中 (IsTran 为 true) 但事务尚未提交 (IsCommit 为 false)
            if (IsTran && !IsCommit)
            {
                // 记录调试日志，表明将要回滚事务
                Logger.LogDebug("UnitOfWork RollbackTran");
                // 调用 Tenant 的 RollbackTran 方法来回滚事务，撤销所有未提交的更改
                Tenant.RollbackTran();
            }

            // b. 检查是否需要关闭数据库连接
            // 如果数据库连接上仍有未完成的事务 或者 连接已经被标记为关闭
            if (Db.Ado.Transaction != null || IsClose)
                // 则不执行关闭操作，直接返回
                return;
            // 如果没有未完成的事务且连接未被标记关闭，则关闭数据库连接
            Db.Close();
        }

        // 3. Commit 方法
        // 用于显式提交事务
        public bool Commit()
        {
            // a. 检查并提交事务
            // 如果当前处于事务中 (IsTran 为 true) 但事务尚未提交 (IsCommit 为 false)
            if (IsTran && !IsCommit)
            {
                // 记录调试日志，表明将要提交事务
                Logger.LogDebug("UnitOfWork CommitTran");
                // 调用 Tenant 的 CommitTran 方法来提交事务，将所有更改持久化到数据库
                Tenant.CommitTran();
                // 将 IsCommit 标记为 true，表示事务已提交
                IsCommit = true;
            }

            // b. 检查并关闭数据库连接
            // 如果数据库连接上没有未完成的事务 且 连接尚未被标记为关闭
            if (Db.Ado.Transaction == null && !IsClose)
            {
                // 关闭数据库连接
                Db.Close();
                // 将 IsClose 标记为 true，表示连接已关闭
                IsClose = true;
            }

            // 返回事务是否已提交的状态
            return IsCommit;
        }
    }


}
